package ewu

import gui.Layout
import scala.collection.mutable.ArrayBuffer
import ewu._

/**
 * Die Klasse Fall bezieht sich auf eine simple if-Abfrage. Drei Elemente werden übergeben:
 * Eine Bedingung, die ausgewertet werden können soll sowie der entsprechende then-Teil
 * und der else-Teil.
 */

case class Fall (bedingung: BoolExpression, thenTeil: Anweisungsfolge,
                                               elseTeil: Anweisungsfolge) extends Anweisung {

 override def numerate(num: List[Int]) = {
    var tmpNum1: List[Int] = 1 :: num
    var tmpNum2: List[Int] = 2 :: num
    number = num
    thenTeil.numerate(1 :: tmpNum1)
    elseTeil.numerate(1 :: tmpNum2)
  }

  override def tabbate(i: Int) = {
    tabs = i
    thenTeil.tabbate(i+1)
    elseTeil.tabbate(i+1)
  }

  override def toString(): String = {
    var ausgabe: String = HM.numberString(number)
    ausgabe ++= "IF (" ++ bedingung.toString ++ ")\n"
    ausgabe ++= HM.numberString(1 :: number) ++ "THEN\n"
    ausgabe ++= thenTeil.toString
    ausgabe ++= HM.numberString(2 :: number) ++ "ELSE\n"
    ausgabe ++= elseTeil.toString
    ausgabe ++= HM.numberString(number) ++ "END IF;\n"
    return ausgabe
  }
  
  override def toTabString: String = {
    var ausgabe: String = HM.tabString(tabs)
    ausgabe ++= "IF (" ++ bedingung.toString ++ ") THEN\n"
    ausgabe ++= thenTeil.toTabString
    ausgabe ++= HM.tabString(tabs) ++ "ELSE\n"
    ausgabe ++= elseTeil.toTabString
    ausgabe ++= HM.tabString(tabs) ++ "END IF;\n"
    return ausgabe
  }

  override def trace(env: Environment, aenv: ArrayEnvironment, tt: Layout, h: Int):
                                                                  (String, Boolean, Int) = {
    var ausgabe: String = ""
    var contH = true
    var countH = h

    ausgabe ++= (HM.numberString(number) ++ "IF (" ++ bedingung.toString ++ ") => ")
    if(bedingung.evaluate(env) == Some(true)) {
      ausgabe ++= "true\n" //++ env.toString ++ "\n"
      var (tmpAusgabe, cont, count) = thenTeil.trace(countH+1, env, tt)
        contH = cont
        countH = count
        ausgabe ++= tmpAusgabe
    }
    else {
      ausgabe ++= "false\n" //++ env.toString ++ "\n"
      if(elseTeil.getLaenge > 0) {
        var (tmpAusgabe, cont, count) = elseTeil.trace(countH+1, env, tt)
          contH = cont
          countH = count
          ausgabe ++= tmpAusgabe
      }
    }

    return (ausgabe, true, countH)
  }

  override def propagate(assV: Anweisung,
                         assN: Anweisung): Anweisungsfolge = {
    var tmp: ArrayBuffer[Anweisung] = ArrayBuffer()

    assV match {
      case Assertion (prefix: String, expr: BoolExpression) =>
        var ass = Assertion("", AND(expr, bedingung).reduce)
        ass.tabbate(tabs+1)
        thenTeil.addAnweisung(ass, 0)
        ass = Assertion("", AND(expr, Not(bedingung).reduce))
        ass.tabbate(tabs+1)
        elseTeil.addAnweisung(ass, 0)
    }

    assN match {
      case Assertion (prefix: String, expr: BoolExpression) =>
        var ass = Assertion("", expr.reduce)
        ass.tabbate(tabs+1)
        thenTeil.addAnweisung(ass, thenTeil.getLaenge)
        ass = Assertion("", expr.reduce)
        ass.tabbate(tabs+1)
        elseTeil.addAnweisung(ass, elseTeil.getLaenge)
    }

    thenTeil.propagate
    elseTeil.propagate

    tmp.append(this)

    return Anweisungsfolge(tmp)
  }

  override def propagate(assI: Anweisung): Anweisungsfolge = null
  
  def getVariables(a: ArrayBuffer[Name]) = {
    bedingung.getVariables(a)
    var a1 = thenTeil.getVariables()
    var a2 = elseTeil.getVariables()
    
    for(i <- 0 to a1.length-1) {
      if(!a.contains(a1(i)))
        a.append(a1(i))
    }
      
    for(i <- 0 to a2.length-1) {
        if(!a.contains(a2(i)))
          a.append(a2(i))
      }
  }
  
  def replaceVariable(fromVar: Name, toVar: Expression) : Unit = {
    bedingung.replaceVariable(fromVar, toVar)
    var a1 = thenTeil.replaceVariable(fromVar, toVar)
    var a2 = elseTeil.replaceVariable(fromVar, toVar)
  }

}


 